home *** CD-ROM | disk | FTP | other *** search
- /*** DISGAS.C (c) S.Enjoji ***/
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <ctype.h>
-
- int getdata(void);
- void code0f(void);
- void operand(int t, char *p);
-
- struct mnem {
- char type;
- char opsize;
- char opra;
- char oprb;
- char oprc;
- char dmy;
- char *opcode;
- };
-
- extern char *multimn[7][8];
- extern struct mnem mntab[];
- extern struct mnem mn0ftab[];
-
- char code[80],op1[32],op2[32],op3[32],dump[40];
- int mod, reg, rm, op32, ad32, oprsize, fdump;
- unsigned long addr;
- FILE *fp;
- char *opctale[3] = {"B", "W", "L"};
-
- main(int argc,char *argv[])
- {
- char sw;
- int c,d,n,s,t;
- unsigned long start,end,qaddr;
-
- if (argc<2) { /* パラメータの数が少なすぎる */
- puts("Parameter error !\a\n");
- puts("usage:disgas [-d] [-sHex_num] [-eHex_num] [-aHex_num] File");
- puts(" s:Start offset e:End offset");
- puts(" a:Address d:Dump switch");
- exit(1);
- }
- op32 = 1;
- ad32 = 1;
- addr = 0L;
- start = 0L;
- end = 0xffffffffL;
- fdump = 0;
- c = 1;
- while(argv[c][0] == '-') { /* オプションスイッチのチェック */
- sw = tolower(argv[c][1]);
- if(sw == 'd') {
- fdump = 1;
- } else if(sw == 's') {
- if(argv[c][2]) sscanf(&argv[c][2], "%lx", &start);
- else sscanf(argv[++c], "%lx", &start);
- } else if(sw == 'e') {
- if(argv[c][2]) sscanf(&argv[c][2], "%lx", &end);
- else sscanf(argv[++c], "%lx", &end);
- } else if(sw == 'a') {
- if(argv[c][2]) sscanf(&argv[c][2], "%lx", &addr);
- else sscanf(argv[++c], "%lx", &addr);
- }
- c++;
- }
- end += addr - start;
- if((fp=fopen(argv[c],"rb")) == NULL) { /* ファイルがない */
- puts("File not exist !\a\n");
- exit(1);
- }
- printf("%s\n",argv[c]);
- fseek(fp, start, SEEK_SET);
- while( (c = getc(fp)) != EOF && addr <= end) {
- qaddr = addr;
- addr++;
- sprintf(dump,"%02X",c);
- s = mntab[c].opsize; /* オペランドサイズの決定 */
- if(s == 1) oprsize = 0;
- else if (s == 2 && op32 == 1) oprsize = 2;
- else oprsize = 1;
- if(mntab[c].opra == 2 || mntab[c].oprb == 2) { /* modrm の展開 */
- d = getdata();
- rm = d % 8;
- reg = (d >> 3) % 8;
- mod = d >> 6;
- }
- n = 2;
- t = mntab[c].type; /* オペコードの決定 */
- if(t == 0) { /* プリフィックス */
- if(c == 0x66) {
- op32 = 0;
- } else if(c == 0x67) {
- ad32 = 0;
- }
- strcpy(code, mntab[c].opcode);
- n--;
- } else if(t == 1) { /* オペランド無し */
- strcpy(code, mntab[c].opcode);
- n--;
- } else if(t <= 4) { /* 1~3オペランド語尾有り */
- sprintf(code, "%s%s", mntab[c].opcode, opctale[oprsize]);
- n = t;
- } else if(t == 5) { /* 1オペランド語尾無し */
- strcpy(code, mntab[c].opcode);
- } else if(t == 8) {
- code0f();
- n--;
- } else if(t == 9) {
- sprintf(code, ".byte 0x%02x", c);
- n--;
- } else if(t == 10 || t == 11) {
- sprintf(code, "%s%s", multimn[t-10][reg], opctale[oprsize]);
- n++;
- } else if(t == 12) {
- sprintf(code, "%s%s", multimn[2][reg], opctale[oprsize]);
- if(!reg) n++;
- } else if(t == 13) {
- if(reg <= 1 || reg == 6) {
- sprintf(code, "%s%s", multimn[3][reg], opctale[oprsize]);
- } else {
- strcpy(code, multimn[3][reg]);
- }
- }
- if(t) {
- op32 = 1;
- ad32 = 1;
- }
- if(n == 2) { /* オペコード、オペランド文字列の作成 */
- operand(mntab[c].opra,op1);
- sprintf(code,"%-8s%s",code,op1);
- } else if(n == 3) {
- operand(mntab[c].opra,op2);
- operand(mntab[c].oprb,op1);
- sprintf(code,"%-8s%s,%s",code,op1,op2);
- } else if(n == 4) {
- operand(mntab[c].opra,op3);
- operand(mntab[c].oprb,op2);
- operand(mntab[c].oprc,op1);
- sprintf(code,"%-8s%s,%s,%s",code,op1,op2,op3);
- }
- if(fdump) {
- printf("_%08lx: %-40s #%s\n",qaddr,strlwr(code),dump);
- } else {
- printf("_%08lx: %s\n",qaddr,strlwr(code));
- }
- }
- fclose(fp);
- }
-
- int getdata()
- {
- int d;
-
- if((d = getc(fp)) == EOF) {
- fclose(fp);
- exit(1);
- }
- addr++;
- if(fdump) sprintf(dump,"%s %02X",dump,d);
- return d;
- }
-
- void code0f(void)
- {
- int c,d,s,n,t;
-
- c = getdata();
- s = mn0ftab[c].opsize; /* オペランドサイズの決定 */
- if(s == 1) oprsize = 0;
- else if (s == 2 && op32 == 1) oprsize = 2;
- else oprsize = 1;
- if(mn0ftab[c].opra == 2 || mn0ftab[c].oprb == 2) { /* modrm の展開 */
- d = getdata();
- rm = d % 8;
- reg = (d >> 3) % 8;
- mod = d >> 6;
- }
- t = mn0ftab[c].type; /* オペコードの決定 */
- if(t == 1) { /* オペランド無し */
- strcpy(code, mn0ftab[c].opcode);
- n = 1;
- } else if(t <= 4) { /* 1~3オペランド語尾有り */
- sprintf(code, "%s%s", mn0ftab[c].opcode, opctale[oprsize]);
- n = t;
- } else if(t == 5) { /* 1オペランド語尾無し */
- strcpy(code, mn0ftab[c].opcode);
- n = 2;
- } else if(t == 6) { /* 2オペランド語尾無し */
- strcpy(code, mn0ftab[c].opcode);
- n = 3;
- } else if(t == 14 || t == 15) {
- strcpy(code, multimn[t-10][reg]);
- n = 2;
- } else if(t == 16) {
- strcpy(code, multimn[6][reg]);
- /* sprintf(code, "%s%s", multimn[6][reg], opctale[oprsize]);*/
- n = 3;
- } else {
- sprintf(code, ".byte 0x0f,0x%02x", c);
- n = 1;
- }
- op32 = 1;
- ad32 = 1;
- if(n == 2) { /* オペコード、オペランド文字列の作成 */
- operand(mn0ftab[c].opra,op1);
- sprintf(code,"%-8s%s",code,op1);
- } else if(n == 3) {
- operand(mn0ftab[c].opra,op2);
- operand(mn0ftab[c].oprb,op1);
- sprintf(code,"%-8s%s,%s",code,op1,op2);
- } else if(n == 4) {
- operand(mn0ftab[c].opra,op3);
- operand(mn0ftab[c].oprb,op2);
- operand(mn0ftab[c].oprc,op1);
- sprintf(code,"%-8s%s,%s,%s",code,op1,op2,op3);
- }
- }
-